package com.itcast.demo.buildtree.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;

//import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.lang.tree.parser.DefaultNodeParser;
import com.itcast.demo.buildtree.dao.BuildTreeDao;
import com.itcast.demo.buildtree.entity.Area;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/buildTree")
public class BuildTreeController {

    @Autowired
    private BuildTreeDao buildTreeDao;

    @PostMapping("tree")
    /*public List<Area> getTrees() {
        List<Area> areas = buildTreeDao.getAllDatas(1);

        // 将 Area 转换为 TreeNode（动态属性存储方式）
        List<TreeNode<Long>> nodeList = areas.stream()
                .map(area -> {
                    TreeNode<Long> node = new TreeNode<>(
                            area.getId(),
                            area.getParentId(),
                            area.getName(),  // 节点名称
                            null             // 权重（可选）
                    );
                    Map<String, Object> extra = node.getExtra();
                    if (extra == null) {
                        extra = new HashMap<>();
                        node.setExtra(extra); // 初始化 extra
                    }
                    // 将 Area 对象的所有属性存入 TreeNode 的额外字段（使用 BeanUtil）
                    BeanUtil.beanToMap(area, false, true)
                            .forEach(new BiConsumer<String, Object>() {
                                @Override
                                public void accept(String s, Object o) {
                                    node.getExtra().put(s, o); // 存储额外属性
                                    node.getExtra().remove("children"); // 移除 children，避免递归问题
                                }
                            });
                    return node;
                })
                .collect(Collectors.toList());

        // 构建树形结构（根节点 parentId=0）
        List<Tree<Long>> treeList = TreeUtil.build(nodeList, 0L, new DefaultNodeParser<>());

        // 转换回 Area 结构
        return convertTreeToArea(treeList);
    }

    // 将 Hutool Tree 转换为 Area 树
    private List<Area> convertTreeToArea(List<Tree<Long>> treeList) {
        return treeList.stream()
                .map(this::convertSingleTree)
                .collect(Collectors.toList());
    }

    private Area convertSingleTree(Tree<Long> tree) {
        // 从 Tree 节点的动态属性中提取数据（替代 getExtra()）
        Area area = BeanUtil.toBean(tree, Area.class);

        // 递归处理子节点
        if (CollUtil.isNotEmpty(tree.getChildren())) {
            List<Area> children = convertTreeToArea(tree.getChildren());
            area.setChildren(children);
        } else {
            area.setChildren(CollUtil.newArrayList()); // 避免 null
        }

        return area;
    }*/
    public List<Area> getTrees() {

        List<Area> areas = buildTreeDao.getAllDatas(1);
        Map<Long, Area> nodeMap = areas.stream().collect(Collectors.toMap(Area::getId, Function.identity()));

        List<Area> rootNodes = areas.stream().filter(node -> node.getParentId() == 0)
                .peek(rootNode -> buildTree(rootNode, nodeMap))
                .collect(Collectors.toList());

        return rootNodes;
    }

    private static void buildTree(Area node, Map<Long, Area> nodeMap) {
        nodeMap.values()
                .stream()
                .filter(childNode -> childNode.getParentId().equals((node.getId())))
                .forEach(childNode -> {
                    node.getChildren().add(childNode);
                    buildTree(childNode, nodeMap);
                });
    }
}
